"""
	闭包:
		三要素:
			1, 必须要有一个内嵌函数
			2, 内嵌函数必须引用外部函数中的变量
			3, 外部函数返回值必须是内嵌函数

		语法:
			def 外部函数名(参数):
				外部变量 = 1
				def 内部函数名(参数):
					使用外部变量
				return 内部函数名

		调用:
			变量 = 外部函数名(参数) # 必须先调用外部函数,才能返回内部函数调用
			变量(参数) # 调用内部函数

"""


# 闭包
def fun1():
	a = 1
	def fun2():
		print(a)

	return fun2


# 调用外部函数, 返回值是内嵌函数
so = fun1()
# 调用内部函数
so()


# 闭包应用, 典型的面向函数式的思想,缺乏面向对象的封装,多态
def give_gife_money(money):
	"""
	获得压岁钱
	:param money: 给了多少压岁钱
	:return: 返回child_buy方法
	"""
	print(f"得到了{money}快压岁钱!")
	def child_buy(target, price):
		"""
		孩子购买商品
		:param target: 需要购买的商品
		:param price: 商品单价
		"""

		nonlocal money
		if money >= price:
			money -= price
			print(f"孩子花了{price}块钱, 购买了{target}商品, 压岁钱还剩{money}块钱")
		else:
			print("钱不够咯!")
	return child_buy


# 逻辑可以连续下去, 当内部函数被调用时,不脱离当前逻辑,都可以操作内嵌外部元素!
so = give_gife_money(100)
so("赛车", 98)
